import { ElementPropertyConfig } from '@farris/ide-property-panel';
import { DgControl } from '../../../../utils/dg-control';
import { FormPropertyChangeObject } from '../../../../entity/property-change-entity';
import { UniformEditorDataUtil, FormBindingType } from '@farris/designer-services';
import { FilterCommonProp } from '../../common/property/filter-common-property-config';
import { NotifyOptions } from '@farris/ui-notify';
import { ListFilterFieldsEditorComponent } from './editor/list-filter-fields-editor/list-filter-fields-editor.component';
import { ListFilterFieldsConverter } from './editor/list-filter-fields-editor/list-filter-fields-converter';
import { EventsEditorFuncUtils } from '../../../../utils/events-editor-func';


export class ListFilterProp extends FilterCommonProp {
    propertyConfig: ElementPropertyConfig[];


    getPropConfig(propertyData: any): ElementPropertyConfig[] {
        this.propertyConfig = [];

        // 常规属性
        const basicPropConfig = this.getBasicPropConfig(propertyData, this.viewModelId);
        this.propertyConfig.push(basicPropConfig);

        // 外观属性
        const appearancePropConfig = this.getAppearancePropConfig(propertyData, this.viewModelId);
        this.propertyConfig.push(appearancePropConfig);

        // 行为属性
        const behaviorPropConfig = this.getBehaviorPropConfig(propertyData, this.viewModelId);
        this.propertyConfig.push(behaviorPropConfig);

        // 事件属性
        const eventPropConfig = this.getEventPropertyConfig(propertyData, this.viewModelId);
        this.propertyConfig.push(eventPropConfig);

        return this.propertyConfig;
    }

    public getBasicPropConfig(propertyData: any, viewModelId: string): ElementPropertyConfig {
        const self = this;
        return {
            categoryId: 'basic',
            categoryName: '基本信息',
            properties: [
                {
                    propertyID: 'id',
                    propertyName: '标识',
                    propertyType: 'string',
                    description: '组件的id',
                    readonly: true
                },
                {
                    propertyID: 'type',
                    propertyName: '控件类型',
                    propertyType: 'select',
                    description: '组件的类型',
                    iterator: [{ key: propertyData.type, value: DgControl[propertyData.type].name }],
                    readonly: true
                },
                {
                    propertyID: 'controlSource',
                    propertyName: '筛选方式',
                    propertyType: 'select',
                    description: '筛选方式选择',
                    iterator: [{ key: 'light', value: '轻量筛选' }, { key: 'normal', value: '常规筛选' }],
                    refreshPanelAfterChanged: true,
                    readonly: this.checkCanChangeControlSource(propertyData)
                }
            ],
            setPropertyRelates(changeObject: FormPropertyChangeObject, data, parameters) {
                if (!changeObject) {
                    return;
                }
                switch (changeObject.propertyID) {
                    case 'controlSource': {
                        // 轻量筛选条比常规筛选多三种控件类型，切换时给出提示，并强制删除
                        self.changeControlSource(changeObject, propertyData, viewModelId);
                    }
                }
            }
        };
    }

    public getAppearancePropConfig(propertyData: any, viewModelId: string): ElementPropertyConfig {
        const self = this;
        return {
            categoryId: 'appearance',
            categoryName: '外观',
            properties: [

                {
                    propertyID: 'alLeft',
                    propertyName: '表单左对齐',
                    propertyType: 'boolean',
                    description: '表单是否左侧对齐',
                    defaultValue: true,
                    visible: propertyData.controlSource === 'normal',
                    controlSource: 'normal'
                },
                {
                    propertyID: 'autoWidth',
                    propertyName: '自适应列宽',
                    propertyType: 'boolean',
                    description: '列宽是否自动调整',
                    defaultValue: false,
                    visible: propertyData.controlSource === 'normal',
                    controlSource: 'normal'
                },
                {
                    propertyID: 'filterClass',
                    propertyName: '筛选项样式',
                    propertyType: 'string',
                    description: '筛选项样式设置',
                    visible: !propertyData.autoWidth && propertyData.controlSource === 'normal',
                    controlSource: 'normal'
                },
                {
                    propertyID: 'autoLabel',
                    propertyName: '自适应标签宽度',
                    propertyType: 'boolean',
                    description: '标签宽度是否自动调整',
                    defaultValue: true,
                    visible: propertyData.controlSource === 'normal',
                    controlSource: 'normal'
                },
                {
                    propertyID: 'showReminder',
                    propertyName: '启用提示',
                    propertyType: 'boolean',
                    defaultValue: false,
                    description: '是否显示提示，一般用于前置任务中',
                    visible: propertyData.controlSource === 'light',
                    controlSource: 'light'
                },
                {
                    propertyID: 'showExtendInSidebar',
                    propertyName: '启用侧边栏收折',
                    propertyType: 'boolean',
                    defaultValue: true,
                    description: '是否在侧边栏中展示收起的控件',
                    visible: propertyData.controlSource === 'light',
                    controlSource: 'light'
                }
            ],
            setPropertyRelates(changeObject: FormPropertyChangeObject, data, parameters) {
                if (!changeObject) {
                    return;
                }
                switch (changeObject.propertyID) {
                    case 'autoWidth': {
                        const filterClass = this.properties.find(p => p.propertyID === 'filterClass');
                        if (filterClass) {
                            filterClass.visible = !changeObject.propertyValue && propertyData.controlSource === 'normal';
                        }
                        break;
                    }
                }
            }
        };
    }

    public getBehaviorPropConfig(propertyData: any, viewModelId: string): ElementPropertyConfig {
        const visibleProp = this.getVisiblePropertyEntity(propertyData, viewModelId);
        const inputConfig = {
            categoryId: 'behavior',
            categoryName: '行为',
            properties: [
                visibleProp,
                {
                    propertyID: 'disable',
                    propertyName: '是否禁用',
                    propertyType: 'unity',
                    description: '是否禁用',
                    editorParams: {
                        controlName: UniformEditorDataUtil.getControlName(propertyData),
                        constType: 'enum',
                        editorOptions: {
                            types: ['const', 'stateMachine'],
                            enums: [{ key: true, value: '是' }, { key: false, value: '否' }],
                            stateMachine: this.stateMachineService.stateMachineMetaData
                        }
                    }
                },
                {
                    propertyID: 'filterList',
                    propertyName: '筛选条字段',
                    propertyType: 'modal',
                    description: '筛选条字段设置',
                    editor: ListFilterFieldsEditorComponent,
                    editorParams: { viewModelId, controlSource: propertyData.controlSource },
                    converter: new ListFilterFieldsConverter()
                },
                {
                    propertyID: 'liveSearch',
                    propertyName: '实时搜索',
                    propertyType: 'boolean',
                    description: '是否启用实时搜索',
                    defaultValue: false,
                    visible: propertyData.controlSource === 'normal',
                    controlSource: 'normal'
                },
                {
                    propertyID: 'binding',
                    propertyName: '默认值绑定',
                    propertyType: 'unity',
                    description: '默认值绑定设置',
                    editorParams: {
                        controlName: UniformEditorDataUtil.getControlName(propertyData),
                        editorOptions: {
                            types: ['variable'],
                            variables: UniformEditorDataUtil.getVariables(viewModelId, this.domService),
                            getVariables: () => UniformEditorDataUtil.getVariables(viewModelId, this.domService),
                            newVariableType: 'String'
                        }
                    }
                }
            ]
        };

        return inputConfig;
    }



    private getEventPropertyConfig(propertyData: any, viewModelId: string): ElementPropertyConfig {
        const self = this;
        const domService = this.domService;
        const webCmdService = this.webCmdService;
        const formBasicService = this.formBasicService;
        const eventEditorService = this.eventEditorService;
        let eventList = [
            {
                label: 'query',
                name: '查询事件'
            },
            {
                label: 'searchChange',
                name: '搜索变化事件'
            },
        ];
        return {
            categoryId: 'eventsEditor',
            categoryName: '事件',
            hideTitle: true,
            properties: EventsEditorFuncUtils.formProperties(eventEditorService, formBasicService, domService, webCmdService, propertyData, viewModelId, eventList),
            tabId: 'commands',
            tabName: '交互',
            setPropertyRelates(changeObject, data, parameters) {
                delete propertyData[viewModelId];
                EventsEditorFuncUtils.saveRelatedParameters(eventEditorService, domService, webCmdService, propertyData, viewModelId, eventList, parameters);
                this.properties = EventsEditorFuncUtils.formProperties(eventEditorService, formBasicService, domService, webCmdService, propertyData, viewModelId, eventList);
            }
        };
    }

    /**
     * 变更控件筛选方式后需要先判断是否包含常规筛选不支持的控件，若有，给出提示信息
     */
    private changeControlSource(changeObject: FormPropertyChangeObject, propertyData: any, viewModelId: string) {
        const { msg, unSupportedFilterId } = this.checkSpecialControlTypeInLightFilter(changeObject, propertyData);
        if (msg) {
            changeObject.propertyValue = 'light';
            const listFilterElement = this.domService.domDgMap.get(propertyData.id);

            // 因为question异步，所以回调方法是在formService.afterPropertyChange方法之后执行的，所以dom结构的变更需要单独处理
            this.msgService.question('常规筛选不支持以下控件，切换后将移除：' + msg + '，确认移除？',
                () => {
                    // 确认变更
                    propertyData.filterList = propertyData.filterList.filter(f => !unSupportedFilterId.includes(f.id));

                    listFilterElement.filterList = propertyData.filterList;
                    listFilterElement.controlSource = 'normal';
                    propertyData.controlSource = 'normal';
                    this.changeRelateCategory(propertyData, viewModelId);

                    // 再次触发组件的变更事件，用于刷新页面显示
                    if (propertyData.elementChanged) {
                        changeObject.propertyValue = 'normal';
                        propertyData.elementChanged.next(changeObject);
                    }
                    // this.checkHasDefaultValue(propertyData);

                },
                () => {
                    // 不变更
                    changeObject.propertyValue = 'light';
                    propertyData.controlSource = 'light';
                    listFilterElement.controlSource = 'light';
                });
        } else {
            this.changeRelateCategory(propertyData, viewModelId);
            // this.checkHasDefaultValue(propertyData);
        }
    }
    /**
     * 轻量筛选比常规筛选多三种控件类型。所以从轻量筛选切换到常规筛选时，对于不支持的类型给出提示，并强制转换成默认类型
     */
    private checkSpecialControlTypeInLightFilter(changeObject: FormPropertyChangeObject, propertyData: any) {
        let msg = '';
        const unSupportedFilterId = [];

        // 常规筛选不支持可变日期、可变数值、单选框控件，故增加检测，并给出提示
        if (changeObject.propertyValue === 'normal' && propertyData.filterList && propertyData.filterList.length) {
            const flexibleDates = [];
            const flexibleNumbers = [];
            const boolChecks = [];

            propertyData.filterList.forEach(element => {
                switch (element.control.controltype) {
                    case 'flexibleDate': {
                        unSupportedFilterId.push(element.id);
                        flexibleDates.push(element.name);
                        break;
                    }
                    case 'flexibleNumber': {
                        unSupportedFilterId.push(element.id);
                        flexibleNumbers.push(element.name);
                        break;
                    }
                    case 'bool-check': {
                        unSupportedFilterId.push(element.id);
                        boolChecks.push(element.name);
                        break;
                    }
                }
            });

            if (flexibleDates.length) {
                msg = ' 可变日期控件【' + flexibleDates.join('、') + '】';
            }
            if (flexibleNumbers.length) {
                msg = msg + (msg ? '、' : '') + ' 可变数值控件【' + flexibleNumbers.join('、') + '】';
            }
            if (boolChecks.length) {
                msg = msg + (msg ? '、' : '') + ' 单选框控件【' + boolChecks.join('、') + '】';
            }
        }

        return { msg, unSupportedFilterId };
    }

    private changeRelateCategory(propertyData: any, viewModelId: string) {
        // 变更【外观分类】下的属性
        const newAppearancePropConfig = this.getAppearancePropConfig(propertyData, viewModelId);
        const currentAppearanceConfig = this.propertyConfig.find(cat => cat.categoryId === 'appearance');
        Object.assign(currentAppearanceConfig, newAppearancePropConfig);

        // 变更【行为分类】下的属性
        const newBehaviorPropConfig = this.getBehaviorPropConfig(propertyData, viewModelId);
        const currentBehaviorConfig = this.propertyConfig.find(cat => cat.categoryId === 'behavior');
        Object.assign(currentBehaviorConfig, newBehaviorPropConfig);
    }

    /**
     * 校验是否可以切换筛选类型：放在header下的轻量筛选（前置任务）不能切换为常规筛选
     */
    private checkCanChangeControlSource(propertyData: any): boolean {
        if (propertyData.controlSource === 'normal') {
            return false;
        }
        const grandParentElement = propertyData.parent && propertyData.parent.parent;
        if (grandParentElement && grandParentElement.type === DgControl.ContentContainer.type &&
            grandParentElement.appearance && grandParentElement.appearance.class &&
            grandParentElement.appearance.class.includes('f-page-header-base')) {
            return true;
        }
        return false;
    }

    /**
     * 两种类型筛选的默认值变量结构不一样，所以要给出提示信息
     */
    private checkHasDefaultValue(propertyData: any) {
        if (propertyData.binding && propertyData.binding.type === FormBindingType.Variable) {
            this.notifyService.warning({
                msg: '两种筛选方式支持的默认值绑定变量的结构不一致，请重新配置！', timeout: 6000
            } as NotifyOptions);
        }
    }
}
